package com.iussoft.receiveData.manager;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.apache.api.vo.ResultMsg;
import com.apache.cache.service.impl.LoadCacheFactory;
import com.apache.exception.BusinessException;
import com.apache.tools.DataMap;
import com.apache.tools.DateUtils;
import com.apache.tools.StrUtil;
import com.apache.tools.UUIDUtil;
import com.iussoft.analyze.utils.DataAnalyzeUtil;
import com.iussoft.manager.RedisManager;
import com.iussoft.mysql.ReqParamVo;
import com.iussoft.mysql.UnifiedDataDao;
import com.iussoft.mysql.util.StrTools;
import com.iussoft.tools.JedisPoolFactory;
import com.iussoft.tools.LoggerUtil;
import com.iussoft.tools.UnityErrorCode;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description: manager
 * @author: Hou Dayu
 * @date: Created in 2020/3/11
 */
@Service("receiveManager")
public class ReceiveManager {

    @Autowired
    private UnifiedDataDao unifiedDataDao;
    @Autowired
    private RedisManager redisManager;
    public static final String INTER_RELATION_KEY="dxpInterfaceRelation";//接口关系缓存KEY

    public JSONObject getDxSysIntRelation(String requestCode){
        String data = redisManager.getCacheInfo(requestCode, JedisPoolFactory.DATABASE);
        if (StrUtil.isNull(data)) {
            ReqParamVo vo = new ReqParamVo();
            vo.setWheres("requestCode",requestCode);
            vo.setTableName("dx_sys_int_relation");
            DataMap<String> map = unifiedDataDao.selectById(vo);
            if(map == null || map.isEmpty()){
                return null;
            }
            JSONObject json = new JSONObject();
            json.put("fromInterfaceCode",map.get("fromInterfaceCode"));
            json.put("fromServerId",map.get("fromServerId"));
            json.put("requestCode",map.get("requestCode"));
            json.put("requestPwd",map.get("requestPwd"));
            json.put("exchangeMode",map.get("exchangeMode"));
            json.put("sysEname",map.get("sysEname"));
            json.put("appId",map.get("toServerId"));
            json.put("appKey",map.get("toInterfaceCode"));
            redisManager.createObjCache(requestCode,json.toJSONString(),86400, JedisPoolFactory.DATABASE);
            return json;
        }else{
            return JSON.parseObject(data);
        }
    }

    public JSONObject getInterfaceInfo(String code){
        ReqParamVo vo = new ReqParamVo();
        vo.setWheres("interfaceCode",code);
        vo.setTableName("dx_interface_reg");
        DataMap<String> data = unifiedDataDao.selectById(vo);
        if (null != data) {
            JSONObject json = new JSONObject();
            json.put("fromInterfaceCode",data.get("interfaceCode"));
            json.put("fromServerId",data.get("infoId"));
            json.put("requestCode",data.get("interfaceCode"));
            json.put("requestPwd","");
            json.put("exchangeMode",data.get("exchangeMode"));
            json.put("sysEname",data.get("sysEname"));
            json.put("interfaceUri",data.get("interfaceUri"));
            if("ftp".equalsIgnoreCase(data.get("interfaceProtocol"))) {
                json.put("interfaceProtocol",data.get("interfaceProtocol"));
                json.put("interfacePort", data.get("interfacePort"));
                json.put("ftpUserName", data.get("ftpUserName"));
                json.put("ftpPwd", data.get("ftpPwd"));
                json.put("sftpKey", data.get("sftpKey"));
                json.put("ftpPath", data.get("ftpPath"));
            }
            return json;
        }
        return null;
    }

    public JSONObject getInterfaceInfoForCode(String code){
        JSONObject json = getDxSysIntRelation(code);
        if(json !=null){//认证code
            return getInterfaceById(json.getString("fromServerId"),json.getString("requestPwd"));
        }
        return getInterfaceInfo(code);//接口Code
    }

    /**
     * 获取接口注册信息
     */
    private JSONObject getInterfaceById(String infoId,String requestPwd){
        Object params = LoadCacheFactory.getInstance().getCacheManager("intsign").getCacheCloneByKey(infoId);
        JSONObject json = new JSONObject();
        if(null == params) {
            DataMap info = selectById("dxInterfaceReg", infoId);
            if(info != null && !info.isEmpty()) {
                json.putAll(info);
                LoadCacheFactory.getInstance().getCacheManager("intsign").createCacheObject(infoId, json.toJSONString());
            }
        } else {
            json = JSON.parseObject(String.valueOf(params));
        }
        JSONObject data = new JSONObject();
        data.put("fromInterfaceCode",json.get("interfaceCode"));
        data.put("fromServerId",json.get("infoId"));
        data.put("requestCode",json.get("interfaceCode"));
        data.put("requestPwd",requestPwd);
        data.put("exchangeMode",json.get("exchangeMode"));
        data.put("sysEname",json.get("sysEname"));
        data.put("interfaceUri",json.get("interfaceUri"));
        if("ftp".equalsIgnoreCase(json.getString("interfaceProtocol"))) {
            data.put("interfaceProtocol",json.get("interfaceProtocol"));
            data.put("interfacePort", json.get("interfacePort"));
            data.put("ftpUserName", json.get("ftpUserName"));
            data.put("ftpPwd", json.get("ftpPwd"));
            data.put("sftpKey", json.get("sftpKey"));
            data.put("ftpPath", json.get("ftpPath"));
        }
        return data;
    }

    public List<DataMap> select(String ObjName, Map<String,String> param) throws BusinessException {
        ReqParamVo vo = new ReqParamVo();
        vo.setWheres(param);
        vo.setTableName(StrTools.upperCharToUnderLine(ObjName));
        return unifiedDataDao.select(vo);
    }

    public List<DataMap> select(String ObjName, ReqParamVo vo) throws BusinessException {
        if(StrUtil.isNull(vo.getTableName())) {
            vo.setTableName(StrTools.upperCharToUnderLine(ObjName));
        }
        return unifiedDataDao.select(vo);
    }

    public DataMap<String> selectById(String ObjName, String infoId) throws BusinessException {
        Map<String, String> param = new HashMap<>();
        param.put("infoId",infoId);
        ReqParamVo vo = new ReqParamVo();
        vo.setWheres(param);
        vo.setTableName(StrTools.upperCharToUnderLine(ObjName));
        return unifiedDataDao.selectById(vo);
    }

    /**
     * 配置规则
     */
    public DataMap<String> getRuleSite(String infoId){
        ReqParamVo vo = new ReqParamVo();
        vo.setWheres("interfaceId",infoId);
        vo.setTableName("dx_gw_rule_site");
        DataMap info = unifiedDataDao.selectById(vo);
        if(null == info){
            info = new DataMap();
        }
        return info;
    }

    public List getInterfaceParams(String serverId,String formatType){
        ReqParamVo param = new ReqParamVo();
        param.setTableName("dx_msg_format_set");
        param.setWheres("interfaceId",serverId);
        param.setWheresIn("msgType",StrUtil.doNull(formatType,"'resp'"));//报文格式类型(req,resp)
        param.setOrderStr(" param_parent ,param_ename");
        List<DataMap> list = unifiedDataDao.select(param);
        return list;
    }

    public JSONObject getInterfaceInfoById(String infoId){
        Object params = LoadCacheFactory.getInstance().getCacheManager("intsign").getCacheCloneByKey(infoId);
        JSONObject json = new JSONObject();
        if(null == params) {
            DataMap info = selectById("dxInterfaceReg", infoId);
            if(info != null && !info.isEmpty()) {
                json.putAll(info);
                LoadCacheFactory.getInstance().getCacheManager("intsign").createCacheObject(infoId, json.toJSONString());
            }
        } else {
            json = JSON.parseObject(String.valueOf(params));
        }
        return json;
    }

    public String sendHttp(String url, MultipartFile file, InputStream inpt,String inputFilename,String fileName,Map<String,String> headParams,Map<String,String> urlParams) {
        CloseableHttpResponse response = null;
        CloseableHttpClient client = null;
        try {
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(1000).setSocketTimeout(60000).build();
            StringBuilder sb = new StringBuilder(url);
            if(!StrUtil.isEmpty(urlParams) && !urlParams.isEmpty()){
                if(url.indexOf("?")==-1){
                    sb.append("?");
                } else {
                    sb.append("&");
                }
                for (Map.Entry<String,String> entry : urlParams.entrySet()) {
                    sb.append(entry.getKey()+"="+ entry.getValue()+"&");
                }
            }
            // 构造请求
            HttpPost httpPost = new HttpPost(sb.toString());
            client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            if(file != null) {
                builder.setCharset(Charset.forName("UTF-8")).addBinaryBody(inputFilename, file.getInputStream(), ContentType.APPLICATION_OCTET_STREAM, file.getOriginalFilename());
            } else {
                builder.setCharset(Charset.forName("UTF-8")).addBinaryBody(inputFilename, inpt, ContentType.APPLICATION_OCTET_STREAM, fileName);
            }
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            if(!StrUtil.isEmpty(headParams) && !headParams.isEmpty()){
                for (Map.Entry<String,String> entry : headParams.entrySet()) {
                    httpPost.setHeader(entry.getKey(), entry.getValue());
                }
            }
            response = client.execute(httpPost);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                String line = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
                return line;
            }
        } catch (Exception e) {
            LoggerUtil.error("连接失败：",e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                if(null != client) {
                    client.close();
                }
            } catch (IOException e) {
                LoggerUtil.error("流关闭失败：",e);
            }
        }
        return null;
    }

    public String sendFtp(JSONObject interfaceInfo, InputStream inpt, String fileName, Map<String,String> urlParams){
        String directory = "/"+DateUtils.format(new Date(),"yyyyMM")+"/";
        if(StrUtil.isNull(fileName)){
            throw new BusinessException(UnityErrorCode.REQ_PARAM_INCOMPLETE.getDesc());
        }
        FTPClient ftpClient = DataAnalyzeUtil.getFtpClient(interfaceInfo);
        if(ftpClient == null){
            LoggerUtil.infoSource("traceId = {}; requestTime = {}; interfaceCode = {}; errorMessage = 创建ftpClient失败; infoType = warning", UUIDUtil.getUUID("",32), DateUtils.Now.fmt_yyyyMMdd_HHmmss(), interfaceInfo.getString("interfaceCode"));
            throw new BusinessException("FTP连接失败");
        }
        String flag = null;
        try {
            //ftpClient.changeWorkingDirectory(interfaceInfo.getString("ftpPath"));
            directory = StrUtil.doNull(interfaceInfo.getString("ftpPath"),directory);
            if (!ftpClient.changeWorkingDirectory(directory)) {
                ftpClient.makeDirectory(directory);
                ftpClient.changeWorkingDirectory(directory);
            }
            if (ftpClient.storeFile(new String(fileName.getBytes("UTF-8"),"ISO-8859-1"), inpt)) {
                flag = JSON.toJSONString(new ResultMsg(UnityErrorCode.SUCCESSFUL.getValue(),fileName+"文件上传成功"));
            }
        } catch (IOException e) {
            LoggerUtil.error("上传失败",e);
            flag = JSON.toJSONString(new ResultMsg(UnityErrorCode.UNKNOWN_ABNORMAL.getValue(),fileName+"文件上传失败"));
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                }
            }
        }
        return flag;
    }
}
